package zju.lzy.service.stat;


import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import zju.lzy.dto.StatDTO;
import zju.lzy.mapper.DeviceMapper;
import zju.lzy.mapper.StatMapper;
import zju.lzy.util.BSUtil;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
public class StatService {

    private static final Logger logger = LoggerFactory.getLogger(StatService.class);

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private StatMapper statMapper;

    public void start() {
        BSUtil.tpe.execute(() -> {
            while (true) {
                try {
                    Long timestamp = System.currentTimeMillis();
                    StatDTO statDTO = new StatDTO(
                            timestamp,
                            deviceMapper.getDeviceNum(),
                            deviceMapper.getActiveDeviceNum(),
                            deviceMapper.getTopicNum(),
                            deviceMapper.getActiveTopicNum()
                    );
                    statMapper.insertStat(statDTO);
                    logger.info("统计成功");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 根据指定粒度查询统计数据
     *
     * @param cnt
     * @param timeUnit
     * @return
     */
    public List<StatDTO> getStatWithGranularity(Integer cnt, Integer timeUnit) {
        Integer recordCnt = cnt * timeUnit;
        List<StatDTO> originList = statMapper.getRecentStat(recordCnt);
        logger.info("查到的数量：{}", originList.size());
        List<List<StatDTO>> partition = Lists.partition(originList, timeUnit);
        return partition.stream()
                .map(stats -> {
                    if (stats != null && stats.size() > 0) {
                        return stats.get(0);
                    } else {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
    }

}
